/*
 * Copyright (c) 2011 Peter Vasil
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * 
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * 
 * Neither the name of the project's author nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifndef _OPTIMIZETOOL_H_
#define _OPTIMIZETOOL_H_

#include "Mesh.h"

namespace assembly3d
{
    namespace wiz
    {
        /**
         * @brief Class for mesh optimizations.
         *
        */
        class OptimizeTool
        {
        public:
            OptimizeTool();
            ~OptimizeTool();

            /**
             * @brief Removes duplicate vertices from mesh.
             *
             * @param m The mesh to work on.
             */
            void stitch(Mesh* m);
            /**
             * @brief Removes duplicate vertices from mesh.
             *
             * @param m The mesh to work on.
             * @param a Attribute to check with epsilon.
             * @param epsilon
             */
            void stitch(Mesh* m, Mesh::AttributeType a, float epsilon);

        protected:
        private:
            struct Vertex
            {
                float position[4];
                float normal[4];
                float texCoord[4];
                float tangent[4];
                float bitangent[4];
            };

            void getVertices(Mesh *m, std::vector<OptimizeTool::Vertex>& vertices);

            bool isInRange(float lhs, float rhs, float eps);

            bool vertexPosEquals(const OptimizeTool::Vertex& lhs,
                                 const OptimizeTool::Vertex& rhs, float eps);
            bool vertexNormalEquals(const OptimizeTool::Vertex& lhs,
                                    const OptimizeTool::Vertex& rhs, float eps);
            bool vertexTexCoordEquals(const OptimizeTool::Vertex& lhs,
                                      const OptimizeTool::Vertex& rhs, float eps);
            bool vertexTangentEquals(const OptimizeTool::Vertex& lhs,
                                     const OptimizeTool::Vertex& rhs, float eps);
            bool vertexBitangentEquals(const OptimizeTool::Vertex& lhs,
                                       const OptimizeTool::Vertex& rhs, float eps);
            int findFirstIndexEqualsEps(std::vector<OptimizeTool::Vertex> verts,
                                        OptimizeTool::Vertex v,
                                        Mesh::AttributeType a, float e);
            bool vertexEquals(const OptimizeTool::Vertex& lhs,
                              const OptimizeTool::Vertex& rhs);
            int findFirstIndexEquals(std::vector<OptimizeTool::Vertex> verts,
                                     OptimizeTool::Vertex v);

        };
    }
}



#endif  // _OPTIMIZETOOL_H_
